﻿using System;
using System.Collections.Generic;
using System.Text;
using InfoJetSoft.Service.XPath.Tokens;

//CID 0766 //2011.01.23 //Begin
namespace InfoJetSoft.Service.XPath.Exprs
{
    public class OperatorExpr : IExpr
    {
        private Operator _operator = Operator.None;

        public OperatorExpr(Operator oper)
        {
            this._operator = oper;
        }

        public Operator Operator
        {
            get
            {
                return this._operator;
            }
        }

        public object Evaluate(ExprContext context)
        {
            return null;
        }

        //CID 0866 //2011.04.01 //Begin
        public void Visit(IExprVisitor visitor)
        {
        }
        //CID 0866 //2011.04.01 //End

        public void Print(StringBuilder buffer)
        {
            if (this._operator == Operator.Or)
            {
                buffer.Append(" or ");
            }
            else if (this._operator == Operator.And)
            {
                buffer.Append(" and ");
            }
            else if (this._operator == Operator.Equal)
            {
                buffer.Append(" = ");
            }
            else if (this._operator == Operator.NotEqual)
            {
                buffer.Append(" != ");
            }
            else if (this._operator == Operator.Lesser)
            {
                buffer.Append(" < ");
            }
            else if (this._operator == Operator.Greater)
            {
                buffer.Append(" > ");
            }
            else if (this._operator == Operator.LesserEqual)
            {
                buffer.Append(" <= ");
            }
            else if (this._operator == Operator.GreaterEqual)
            {
                buffer.Append(" >= ");
            }
            else if (this._operator == Operator.Add)
            {
                buffer.Append(" + ");
            }
            else if (this._operator == Operator.Subtract)
            {
                buffer.Append(" - ");
            }
            else if (this._operator == Operator.Mul)
            {
                buffer.Append(" * ");
            }
            else if (this._operator == Operator.Div)
            {
                buffer.Append(" div ");
            }
            else if (this._operator == Operator.Mod)
            {
                buffer.Append(" mod ");
            }
            else if (this._operator == Operator.Unary)
            {
                buffer.Append(" - ");
            }
            else if (this._operator == Operator.Slash )
            {
                buffer.Append("/");
            }
            else if (this._operator == Operator.SlashSlash)
            {
                buffer.Append("//");
            }
            else
            {
                throw new Exception("Wrong operator " + this._operator);
            }
        }

        public static OperatorExpr ParseOrOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator) && (nextToken.Value.Equals("or")))
                {
                    parser.MoveNextIndex(1);

                    return new OperatorExpr(Operator.Or);
                }
            }
            return null;
        }

        public static OperatorExpr ParseAndOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator) && (nextToken.Value.Equals("and")))
                {
                    parser.MoveNextIndex(1);

                    return new OperatorExpr(Operator.And);
                }
            }
            return null;
        }

        public static OperatorExpr ParseEqualityOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator))
                {
                    if (nextToken.Value.Equals("="))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Equal);
                    }
                    else if(nextToken.Value.Equals("!="))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.NotEqual);
                    }
                }
            }
            return null;
        }

        public static OperatorExpr ParseRelationalOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator))
                {
                    if (nextToken.Value.Equals("<"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Lesser);
                    }
                    else if (nextToken.Value.Equals(">"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Greater);
                    }
                    else if (nextToken.Value.Equals("<="))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.LesserEqual);
                    }
                    else if (nextToken.Value.Equals(">="))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.GreaterEqual);
                    }
                }
            }
            return null;
        }

        public static OperatorExpr ParseAdditiveOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator))
                {
                    if (nextToken.Value.Equals("+"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Add);
                    }
                    else if (nextToken.Value.Equals("-"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Subtract);
                    }
                }
            }
            return null;
        }

        public static OperatorExpr ParseMultiplicativeOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator))
                {
                    if (nextToken.Value.Equals("*"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Mul);
                    }
                    else if (nextToken.Value.Equals("div"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Div);
                    }
                    else if (nextToken.Value.Equals("mod"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Mod);
                    }
                }
            }
            return null;
        }

        public static OperatorExpr parseUnaryOperator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                if (nextToken.Type.Equals(TokenType.Operator))
                {
                    if (nextToken.Value.Equals("-"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Unary);
                    }
                }
            }
            return null;
        }

        public static OperatorExpr ParseStepSeparator(ExprParser parser)
        {
            Token nextToken = parser.LookupNextToken(1);
            if (nextToken != null)
            {
                //是符号"/"或"//"
                if (nextToken.Type.Equals(TokenType.Operator) && (nextToken.Value.Equals("/") || nextToken.Value.Equals("//")))
                {
                    if (nextToken.Value.Equals("/"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.Slash);
                    }
                    else if (nextToken.Value.Equals("//"))
                    {
                        parser.MoveNextIndex(1);

                        return new OperatorExpr(Operator.SlashSlash);
                    }
                }
            }
            return null;
        }
    }
}
//CID 0766 //2011.01.23 //End
